// src/main/ets/http.ts
import http from '@ohos.net.http';
import prompt from '@ohos.prompt';
import router from '@ohos.router';

import { ApiResponse } from './types';

const BASE_URL = 'http://172.29.128.1:5000/api';
const TOKEN_EXPIRE_BUFFER = 300000; // 提前5分钟判断token过期

export class HttpClient {
  private httpRequest: http.HttpRequest;
  private isRefreshing = false;
  private refreshSubscribers: ((token: string) => void)[] = [];

  constructor() {
    this.httpRequest = http.createHttp();
  }

  /**
   * 发送POST请求
   * @param url 请求路径
   * @param data 请求数据
   * @param retryCount 重试次数（内部使用）
   */
  async post<T extends ApiResponse>(url: string, data: object, retryCount = 0): Promise<T> {
    try {
      // 获取当前token
      const token = AppStorage.get<string>('accessToken');

      // 构造请求头
      const headers: Record<string, string> = {
        'Content-Type': 'application/json'
      };

      // 如果存在token则添加到header
      if (token && this.isTokenValid()) {
        headers['Authorization'] = `Bearer ${token}`;
      }

      const response = await this.request<T>({
        url: `${BASE_URL}${url}`,
        method: http.RequestMethod.POST,
        headers,
        data: JSON.stringify(data)
      });

      return response;
    } catch (error) {
      // 处理401未授权错误（token过期）
      if (error.responseCode === 401 && retryCount === 0) {
        try {
          // 尝试刷新token
          const newToken = await this.refreshToken();
          if (newToken) {
            // 使用新token重试请求
            return this.post<T>(url, data, retryCount + 1);
          }
        } catch (refreshError) {
          console.error('Refresh token failed:', refreshError);
        }

        // 刷新失败，跳转到登录页
        this.clearAuthAndRedirect();
        throw error;
      }

      // 其他错误直接抛出
      throw error;
    }
  }

  /**
   * 基础请求方法
   */
  private request<T>(options: {
    url: string;
    method: http.RequestMethod;
    headers: Record<string, string>;
    data: string;
  }): Promise<T> {
    return new Promise<T>((resolve, reject) => {
      this.httpRequest.request(
        options.url,
        {
          method: options.method,
          header: options.headers,
          extraData: options.data
        },
        (err, response) => {
          if (err) {
            this.handleNetworkError(err);
            reject(err);
            return;
          }

          try {
            const result: T = JSON.parse(response.result.toString());

            // 处理业务错误
            if (response.responseCode !== 200 || !(result as ApiResponse).success) {
              this.handleBusinessError(result as ApiResponse);
              reject(result);
              return;
            }

            resolve(result);
          } catch (e) {
            this.handleDataParseError(e);
            reject(e);
          }
        }
      );
    });
  }

  /**
   * 刷新Token
   */
  private async refreshToken(): Promise<string | null> {
    // 防止重复刷新
    if (this.isRefreshing) {
      return new Promise((resolve) => {
        this.refreshSubscribers.push((token) => {
          resolve(token);
        });
      });
    }

    this.isRefreshing = true;
    const refreshToken = AppStorage.get<string>('refreshToken');

    if (!refreshToken) {
      this.clearAuthAndRedirect();
      return null;
    }

    try {
      const response = await this.request<ApiResponse<{ accessToken: string }>>({
        url: `${BASE_URL}/auth/refresh`,
        method: http.RequestMethod.POST,
        headers: {
          'Content-Type': 'application/json'
        },
        data: JSON.stringify({ refreshToken })
      });

      if (response.success && response.data) {
        // 存储新token
        AppStorage.setOrCreate('accessToken', response.data.accessToken);

        // 通知所有等待的请求
        this.refreshSubscribers.forEach(callback => callback(response.data.accessToken));
        this.refreshSubscribers = [];

        return response.data.accessToken;
      }

      return null;
    } catch (error) {
      console.error('Refresh token error:', error);
      this.clearAuthAndRedirect();
      return null;
    } finally {
      this.isRefreshing = false;
    }
  }

  /**
   * 检查Token是否有效
   */
  private isTokenValid(): boolean {
    const token = AppStorage.get<string>('accessToken');
    const expireTime = AppStorage.get<number>('tokenExpireTime');

    if (!token || !expireTime) {
      return false;
    }

    return Date.now() < expireTime - TOKEN_EXPIRE_BUFFER;
  }

  /**
   * 清除认证信息并跳转到登录页
   */
  private clearAuthAndRedirect(): void {
    AppStorage.delete('accessToken');
    AppStorage.delete('refreshToken');
    AppStorage.delete('tokenExpireTime');
    AppStorage.delete('userData');

    router.clear();
    router.replace({ url: 'pages/LoginPage' });
  }

  /**
   * 处理网络错误
   */
  private handleNetworkError(err: Error): void {
    console.error('Network error:', err);
    prompt.showToast({
      message: '网络连接异常，请检查网络设置',
      duration: 2000
    });
  }

  /**
   * 处理业务错误
   */
  private handleBusinessError(response: ApiResponse): void {
    console.error('Business error:', response);
    prompt.showToast({
      message: response.message || '请求失败，请稍后重试',
      duration: 2000
    });
  }

  /**
   * 处理数据解析错误
   */
  private handleDataParseError(err: Error): void {
    console.error('Data parse error:', err);
    prompt.showToast({
      message: '数据解析失败',
      duration: 2000
    });
  }
}

// 创建单例实例
const httpClient = new HttpClient();
export default httpClient;